﻿using Ninject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Peninsula.Common;
using Peninsula.DataAccess;
using Peninsula.IServices;

namespace Peninsula.Services
{
    public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : BaseEntity, new()
    {

        [Inject]
        public IRepository<TEntity> Repository { get; set; }
        [Inject]
        public ISiteCache SiteCache { get; set; }

        #region 属性

        /// <summary>
        ///     获取 当前实体的查询数据集
        /// </summary>
        public IQueryable<TEntity> Entities
        {
            get { return Repository.Entities; }
        }

        #endregion

        #region 公共方法



        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public bool IsExist(IQueryable<TEntity> query)
        {
            return Repository.IsExist(query);
        }

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public bool IsExist(Expression<Func<TEntity, bool>> predicate = null)
        {
            return Repository.IsExist(predicate);
        }

        /// <summary>
        ///     插入实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Insert(TEntity entity, bool isSave = true)
        {
            return Repository.Insert(entity, isSave);
        }

        /// <summary>
        ///     批量插入实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Insert(IEnumerable<TEntity> entities, bool isSave = true)
        {
            return Repository.Insert(entities, isSave);
        }


        /// <summary>
        /// 批量插入操作
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="isSave"></param>
        public void BulkInsert(IEnumerable<TEntity> entities, bool isSave = true)
        {
            Repository.BulkInsert(entities, isSave);
        }

        /// <summary>
        ///     删除指定编号的记录
        /// </summary>
        /// <param name="id"> 实体记录编号 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Delete(string id, bool isSave = true)
        {
            return Repository.Delete(id, isSave);
        }

        /// <summary>
        ///     删除实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Delete(TEntity entity, bool isSave = true)
        {
            return Repository.Delete(entity, isSave);
        }

        /// <summary>
        ///     删除实体记录集合
        /// </summary>
        /// <param name="entities"> 实体记录集合 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Delete(IEnumerable<TEntity> entities, bool isSave = true)
        {
            return Repository.Delete(entities, isSave);
        }

        /// <summary>
        ///     删除所有符合特定表达式的数据
        /// </summary>
        /// <param name="predicate"> 查询条件谓语表达式 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true)
        {
            return Repository.Delete(predicate, isSave);
        }

        /// <summary>
        ///     更新实体记录
        /// </summary>
        /// <param name="entity"> 实体对象 </param>
        /// <param name="isSave"> 是否执行保存 </param>
        /// <returns> 操作影响的行数 </returns>
        public int Update(TEntity entity, Func<TEntity, object[]> getKeys = null, bool isSave = true, bool updateTime = true)
        {
            return Repository.Update(entity, getKeys, isSave, updateTime);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="setter"></param>
        /// <param name="saveChange"></param>
        /// <returns></returns>
        public int Update(Expression<Func<TEntity, bool>> predicate, Func<TEntity, TEntity> setter, bool isSave = true)
        {
            return Repository.Update(predicate, setter, isSave);
        }


        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="isSave"></param>
        public void BulkUpdate(IEnumerable<TEntity> entities, bool isSave = true)
        {
            Repository.BulkUpdate(entities);
        }


        public void BulkUpdate(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> setter, bool isSave = true)
        {
            Repository.BulkUpdate(predicate, setter, isSave);
        }

        /// <summary>
        ///     查找指定主键的实体记录
        /// </summary>
        /// <param name="key"> 指定主键 </param>
        /// <returns> 符合编号的记录，不存在返回null </returns>
        public TEntity GetById(string id)
        {
            return Repository.GetById(id);
        }


        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public TEntity Get(Expression<Func<TEntity, bool>> predicate)
        {
            return Repository.Get(predicate);
        }

        public int ExecuteNonQuery(string sql)
        {
            return Repository.ExecuteNonQuery(sql);
        }

        public List<T> QuerySql<T>(string sql, params object[] parameters)
        {
            return Repository.QuerySql<T>(sql, parameters);
        }

        public int ExecuteSqlCommand(string sql, params object[] parameters)
        {
            return Repository.ExecuteSqlCommand(sql, parameters);
        }

        /// <summary>
        /// 保存变动
        /// </summary>
        /// <returns></returns>
        public int SaveChanges()
        {
            return Repository.SaveChanges();
        }

        /// <summary>
        /// 获取数据，并缓存全表
        /// </summary>
        /// <param name="refresh">强制刷新缓存</param>
        /// <returns>全表数据</returns>
        public List<TEntity> CacheFullTable(bool refresh = false)
        {
            string key = typeof(TEntity).Name + "Table";

            return SiteCache.Get(key, () =>
            {
                return Repository.Entities.ToList();
            }, new TimeSpan(24, 0, 0), refresh: refresh);
        }
        #endregion
    }
}
